﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace MyPublisher.Composition
{
    public class CompositionFactory
    {
        internal class CompositionData<T>
        {
            internal T Attribute { get; set; }
            internal Type Type { get; set; }
        }

        public static CompositionFactory Instance { get; private set; }
        
        private static void LoadCompositionAssembly(string name)
        {
            Assembly fopCompositonAssembly = Assembly.Load(name);
            Type[] types = fopCompositonAssembly.GetTypes();
            foreach (Type type in types)
            {
                object[] attributes = type.GetCustomAttributes(typeof(TransformAttribute), true);
                foreach (TransformAttribute attribute in attributes)
                {
                    Instance.Transformers.Add(
                        attribute.Name,
                        new CompositionData<TransformAttribute>() { Attribute = attribute, Type = type });
                }
            }
        }
        static CompositionFactory()
        {
            Instance = new CompositionFactory();
            //LoadCompositionAssembly("MyPublisher.Composition.Fop");
        }

        private Dictionary<string, CompositionData<TransformAttribute>> Transformers { get; set; }
        private CompositionFactory()
        {
            Transformers = new Dictionary<string, CompositionData<TransformAttribute>>();
        }

        public ITransform CreateTransform(FragmentType inputType,FragmentType outputType)
        {
            foreach (KeyValuePair<string, CompositionData<TransformAttribute>> transformer in Transformers)
            {
                if (transformer.Value.Attribute.InputType == inputType &&
                    transformer.Value.Attribute.OutputType == outputType)
                    {
                        return Activator.CreateInstance(transformer.Value.Type) as ITransform; 
                    }
            }

            throw new CompositionException(string.Format("Failed to create transformer input<{0}> output<{1}>",
                inputType.ToString(),
                outputType.ToString()));
        }
    }
}
